package net.food.controller;

import com.google.gson.Gson;
import com.jfinal.json.Json;
import com.jfinal.kit.HttpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import net.food.WxTemplate.*;
import net.food.remotecommon.entity.PrintOrder;
import net.food.remotecommon.entity.Printer;
import net.food.remotecommon.entity.User;
import net.food.remotecommon.service.PrintOrderService;
import net.food.remotecommon.service.PrinterService;
import net.food.remotecommon.service.UserService;
import net.food.util.data.ForData;
import net.food.weixin.util.WechatUtil;
import net.food.weixinpay.WxSubPay.*;

import net.food.weixinpay.WxSubPay.XMLUtil;
import net.food.weixinpay.util.*;
import net.sf.json.JSONObject;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

/**
 * Created by Dawson on 2017/8/23 0023.
 */
@Controller
@RequestMapping(value = "/wx_subpay")
public class WxSubController {

    @Autowired
    private PrintOrderService printOrderService;

    @Autowired
    private PrinterService printerService;

    @Autowired
    private UserService userService;

    /**
     * 支付页面
     *
     * @param modelAndView
     * @param
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/wxpay")
    public ModelAndView pay(ModelAndView modelAndView, @RequestParam String totalPrice, @RequestParam String totalCount, @RequestParam String address, @RequestParam String modelinput, @RequestParam String kindsInput, @RequestParam String printId, HttpServletRequest request) throws IOException {
        User user = (User) request.getSession().getAttribute("user");
        String orderNo = PayUtil.getOutTradeNo();
        String printNo = orderNo;
        String appid = Constant.APPID;
        String timeStamp = PayUtil.createTimestamp();
        String nonceStr = PayCommonUtil.CreateNoncestr();
        String prepayId = getPrepayId(totalPrice, request, orderNo);
        String packages = "prepay_id=" + prepayId;
        String signType = "MD5";
        PrintOrder printOrder = new PrintOrder();
        printOrder.setShopId(user.getShop().getId());
        printOrder.setAddress(address);
        printOrder.setTotalCount(Integer.valueOf(totalCount));
        printOrder.setTotalPrice(Double.valueOf(totalPrice));
        printOrder.setOrderNo(printNo);
        Printer print = printerService.get(printId);
        printOrder.setPrinter(print);
        printOrder.setUserId(user
                .getId());
        printOrderService.persist(printOrder);
        Map<String, String> map1 = new TreeMap<String, String>();
        map1.put("appId", appid);
        map1.put("timeStamp", timeStamp);
        map1.put("nonceStr", nonceStr);
        map1.put("package", packages);
        map1.put("signType", signType);
        String paySign1 = PayUtil.createSign(map1);
        modelAndView.addObject("appId", appid);
        modelAndView.addObject("timeStamp", timeStamp);
        modelAndView.addObject("nonceStr", nonceStr);
        modelAndView.addObject("packages", packages);
        modelAndView.addObject("paySign", paySign1);
        modelAndView.addObject("signType", signType);
        modelAndView.addObject("totalPrice", totalPrice);
        modelAndView.addObject("totalCount", totalCount);
        modelAndView.addObject("orderNo", orderNo);
        modelAndView.addObject("address", address);
        modelAndView.addObject("modelinput", modelinput);
        modelAndView.addObject("kindsInput", kindsInput);
        modelAndView.setViewName("/back/confirmPay");

        return modelAndView;
    }


    /**
     * 获取参数prepay_id
     *
     * @return
     */
    private String getPrepayId(String price, HttpServletRequest request, String orderNo) throws IOException {
        User user = (User) request.getSession().getAttribute("user");

        SortedMap<Object, Object> map = new TreeMap<Object, Object>();
        map.put("appid", Constant.APPID);//公众号id
        map.put("mch_id", "1393973302");//商户号
        /*map.put("sub_mch_id",Constant.SUB_MCHID);//子商户号*/
        map.put("device_info", Constant.DEVICE_INFO);//设备号
        map.put("nonce_str", PayCommonUtil.CreateNoncestr());//随机字符串,不大于32位
        map.put("body", "打印机消费");//商品简单描述
        map.put("out_trade_no", orderNo);//商品订单号,唯一并且不大于32位
        map.put("total_fee", CommonUtil.yuanToFee(price));//商品价格,以分为单位并且不能包含小数
        map.put("spbill_create_ip", InetAddress.getLocalHost()
                .getHostAddress().toString());
        map.put("notify_url", Constant.NOTIFY_URL);//通知地址, 必需外网可访问,不能携带参数
        map.put("trade_type", Constant.TRADE_TYPE);//交易类型

        map.put("openid", user.getUserOpenId().getOpenid());//写死测试
        String sign = PayCommonUtil.createSign("UTF-8", map);
        map.put("sign", sign);
        String requestXML = PayCommonUtil.getRequestXml(map);
        String resultCode = CommonUtil.httpsRequest(Constant.GET_PREPAYID, "POST", requestXML);
        Map<String, String> map2 = null;
        try {
            map2 = XMLUtil.doXMLParse(resultCode);// 解析微信返回的信息，以Map形式存储便于取值
        } catch (JDOMException e) {
            e.printStackTrace();
        }

        return map2.get("prepay_id");
    }


    @RequestMapping(value = "/notify", method = {RequestMethod.GET, RequestMethod.POST})
    public String notify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        InputStream inStream = null;
        try {
            inStream = request.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        try {
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            outSteam.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //交易状态
        String result = null;//获取微信调用我们notify_url的返回信息
        try {
            result = new String(outSteam.toByteArray(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        TreeMap<String, String> param = net.food.weixinpay.util.XMLUtil.parseXmlToMap(result);
        String trade_status = param.get("result_code");
        boolean payresult = false;
        if (trade_status.equals("SUCCESS") && PayUtil.createSign(param).equals(param.get("sign"))) {
            payresult = true;
            String orderNO = param.get("out_trade_no");
            synchronized (this) {
            /**
            *  调用微信模板消息
            */

                PrintOrder printOrder = printOrderService.getByProerties("orderNo", orderNO);
                printOrder.setPayTime(new Date());
                printOrder.setPayState(1);
                printOrderService.update(printOrder);
                User user = userService.get(printOrder.getUserId());
                OrderInfoMode orderInfoMode = new OrderInfoMode();
                orderInfoMode.setFirst("您收到了一条新的订单。");
                orderInfoMode.setTradeDateTime(ForData.dateToStringAll(printOrder.getPayTime()));
                orderInfoMode.setOrderType("打印机订单");
                orderInfoMode.setCustomerInfo(user.getNickname());
                orderInfoMode.setOrderItemName("打印机型号");
                orderInfoMode.setOrderItemData(printOrder.getPrinter().getModel() + printOrder.getPrinter().getType() + "数量" + printOrder.getTotalCount() + "个");
                orderInfoMode.setRemark("请你及时处理订单");
                WechatTemplate wechatTemplate = new WechatTemplate();
                wechatTemplate.setTemplate_id("RSi_5SOLKxQv8NsjXObckubYf5_81h3HF3OTRb8ckqA");
                wechatTemplate.setTouser("o40NVwTPpABW4GinlcTC7wOaLr-k");
                Map<String, TemplateData> data = new HashMap<String, TemplateData>();
                data.put("first", new TemplateData(orderInfoMode.getFirst(), "#173177"));
                data.put("tradeDateTime", new TemplateData(orderInfoMode.getTradeDateTime(), "#173177"));
                data.put("orderType", new TemplateData(orderInfoMode.getOrderType(), "#173177"));
                data.put("customerInfo", new TemplateData(orderInfoMode.getCustomerInfo(), "#173177"));
                data.put("orderItemName", new TemplateData(orderInfoMode.getOrderItemName(), "#173177"));
                data.put("orderItemData", new TemplateData(orderInfoMode.getOrderItemData(), "#173117"));
                data.put("remark", new TemplateData(orderInfoMode.getRemark(), "#173177"));
                wechatTemplate.setData(data);
                String appId = "wx6041a1eff32d3c5e";
                String appserct = "c9daf98df0b9eb939294f9a50858cc4e";
                AccessToken accessToken = TemplateUrl.getAccessToken(appId, appserct);
                JSONObject jsonObject = TemplateUrl.sendTmplMsg(wechatTemplate, accessToken.getAccessToken());
            }
        }
        if (payresult) {

            System.out.println("支付成功 收到扫码支付异步通知 返回success");

            return "SUCCESS";
        } else {
            System.out.println("支付失败");
            return "FAIL";
        }


    }
}


